// ActionScript file
package
{
	import flash.display.DisplayObject;
	import flash.utils.describeType;
	import flash.utils.getQualifiedClassName;
	
	import flex.ui.Popup;
	import flex.utils.Constants;
	
	import mx.collections.ArrayCollection;
	import mx.core.Application;
	import mx.managers.PopUpManager;
	
	/**
	 * Author - Sivakumar Subramani
	 * This class is used to generate flex code equivalent to the object during runtime.
	 * */
	public class ObjectWriter
	{
		private static var objectStr:String = "";
		private static var i:int;
		
		public static function getSourceCode(object:Object, showCode:Boolean = false):String
		{
			if(object is ArrayCollection){
				traceArrayCollection(ArrayCollection(object),"array",true);
			}else{
				traceObject(object);
			}
			var pop:Object = PopUpManager.createPopUp(DisplayObject(Application.application),Popup,false);
			pop.setupData(objectStr);
			return objectStr;
		}
		
		//generates code for collection objects.
		private static function traceArrayCollection(collection:ArrayCollection, collName:String="array", isNewDeclaration:Boolean=false):void
		{
			if(isNewDeclaration){
				//Starts here
				objectStr += "var "+collName+":"+Constants.ARRAYCOLLECTION+" = new "+Constants.ARRAYCOLLECTION+";\n";
			}else{
				objectStr += collName+" = new "+Constants.ARRAYCOLLECTION+";\n";
			}
			if(collection is ArrayCollection && collection){
				for each (var obj:Object in collection){
					var objName:String = "obj"+(++i);
					if(obj is ArrayCollection){
						traceArrayCollection(ArrayCollection(obj),objName,true);
					}else{
						var className:String = getQualifiedClassName(obj).replace("::",".");
						objectStr += "var "+objName+":"+className+"= new "+className+";\n";
					}
					var getItem:XML = describeType(obj);
					if(!(obj is ArrayCollection) && obj){
						for each (var key:Object in getItem..accessor){
							if(obj[key.@name] is ArrayCollection){
								traceArrayCollection(obj[key.@name],objName+"."+key.@name);
							}else if(obj[key.@name] is String){
								objectStr += objName+"."+key.@name+" = '"+obj[key.@name]+"';\n"
							}else if(obj[key.@name] is int || obj[key.@name] is Number){
								objectStr += objName+"."+key.@name+" = "+obj[key.@name]+";\n"
							}else if(obj[key.@name]){
								traceObject(obj[key.@name],objName+"."+key.@name);
							}
						}
					}
					objectStr += collName+".addItem("+objName+");\n";
				}
			}
		}
		
		//generates code for any objects.
		private static function traceObject(obj:Object,nameObj:String = null):void
		{
			var className:String = getQualifiedClassName(obj).replace("::",".");
			var objName:String = "obj"+(++i);
			if(!(obj is ArrayCollection) && obj)
			objectStr += "var "+objName+":"+className+"= new "+className+";\n";
			var getItem:XML = describeType(obj);
			if(!(obj is ArrayCollection) && obj){
				for each (var key:Object in getItem..accessor){
					if(obj[key.@name] is ArrayCollection){
						traceArrayCollection(obj[key.@name],objName+"."+key.@name);
					}else if(obj[key.@name] is String){
						objectStr += objName+"."+key.@name+" = '"+obj[key.@name]+"';\n"
					}else if(obj[key.@name] is int || obj[key.@name] is Number){
						objectStr += objName+"."+key.@name+" = "+obj[key.@name]+";\n"
					}else if(obj[key.@name]){
						traceObject(obj[key.@name],objName+"."+key.@name);
					}
					
				}
			}
			if(nameObj){
				objectStr += nameObj+" = "+objName+"\n";
			}
		}
	}
}